﻿using Engine.FileFormats3D.WR2TerrainLoader.Misc;
using Engine.Graphics;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using WorldRacing2.Configuration.GroundConfig;

namespace WorldRacing2.Configuration.Material
{
    internal class TextureToMaterialFile
    {
        private const byte VERSION = 0x01;

        private Dictionary<string, TexturePropertie> textureProperties;

        public TextureToMaterialFile()
        {
            this.textureProperties = new Dictionary<string, TexturePropertie>();
        }

        public Dictionary<string, TexturePropertie> TextureProperties
        {
            get { return textureProperties; }
            private set { textureProperties = value; }
        }

        public void ToStream(BinaryWriter bw, GroundsFile groundsFile)
        {
            bw.Write(VERSION);
            groundsFile.ToStream(bw);
            bw.Write(this.textureProperties.Count);
            for (int i = 0; i < this.textureProperties.Count; i++)
            {
                this.textureProperties.ElementAt(i).Value.ToStream(bw);
            }
        }

        internal void SetMaterialManagre(MaterialManager materialManager)
        {
            for (int i = 0; i < materialManager.TextureNames.Count; i++)
            {
                if (!this.textureProperties.ContainsKey(materialManager.TextureNames[i]))
                    this.textureProperties.Add(materialManager.TextureNames[i], new TexturePropertie(materialManager.TextureNames[i], GroundControl.DEFAULT_GROUND_NAME, false, false));
            }
        }

        internal void CreateStandardFile(string filename, MaterialManager materialManager)
        {
            this.textureProperties.Clear();

            for (int i = 0; i < materialManager.TextureNames.Count; i++)
            {
                this.textureProperties.Add(materialManager.TextureNames[i], new TexturePropertie(materialManager.TextureNames[i], GroundControl.DEFAULT_GROUND_NAME, false, false));
            }
        }

        public static TextureToMaterialFile FromFile(string filename, out GroundsFile groundsFile)
        {
            groundsFile = new GroundsFile();
            TextureToMaterialFile file;
            if (!File.Exists(filename))
            {
                throw new Exception(string.Format("File doesn´t exist! ({0})", filename));
            }

            using (FileStream fs = new FileStream(filename, FileMode.Open))
            {
                using (BinaryReader br = new BinaryReader(fs))
                {
                    if (br.BaseStream.Length > 0)
                    {
                        switch (br.ReadByte())
                        {
                            case 0x01:
                                return file = LoadV1(br, out groundsFile);

                            default:
                                throw new Exception("Can´t load textureproperties");
                        }
                    }
                }
            }

            throw new Exception("Can´t load textureproperties");
        }

        private static TextureToMaterialFile LoadV1(BinaryReader br, out GroundsFile groundsFile)
        {
            TextureToMaterialFile file = new TextureToMaterialFile();
            groundsFile = GroundsFile.FromStream(br);

            int numberOfTextureProperties = br.ReadInt32();
            for (int i = 0; i < numberOfTextureProperties; i++)
            {
                TexturePropertie texturePropertie = TexturePropertie.FromStream(br);

                if (file.textureProperties.ContainsKey(texturePropertie.TextureName))
                {
                    file.textureProperties[texturePropertie.TextureName] = texturePropertie;
                }
                else
                    file.textureProperties.Add(texturePropertie.TextureName, texturePropertie);
            }

            return file;
        }
    }
}